#pragma once
/*
    一个提供公共方法的头文件
*/
#include <iostream>
#include <sstream>
#include <iomanip>
#include <cctype>
#include <string>
#include <cstdlib>  
#include <ctime> 
#include<jwt-cpp/jwt.h>
#include<fcntl.h>
#include<unistd.h>
using namespace std;
//字符串截取两个元素方法
void cutString(const std::string &target, std::string &str1, std::string &str2, const std::string &sep)
{
    size_t pos = target.find(sep);
    if (pos != std::string::npos)
    {
        str1 = target.substr(0, pos);
        str2 = target.substr(pos + sep.size());
    }
}

// 对url进行解码的方法
std::string urlDecode(const std::string &str)
{
    std::string result;
    result.reserve(str.size());

    for (std::size_t i = 0; i < str.size(); ++i)
    {
        if (str[i] == '%')
        {
            if (i + 2 < str.size() &&
                std::isxdigit(str[i + 1]) &&
                std::isxdigit(str[i + 2]))
            {

                // 提取十六进制值
                std::string hex = str.substr(i + 1, 2);
                std::istringstream iss(hex);
                int charValue;
                iss >> std::hex >> charValue;

                result += static_cast<char>(charValue);
                i += 2;
            }
            else
            {
                // 无效的百分比编码，保留原样
                result += str[i];
            }
        }
        else if (str[i] == '+')
        {
            result += ' ';
        }
        else
        {
            result += str[i];
        }
    }
    return result;
}

//解析base64Url
std::string base64UrlDecode(const std::string& input) {
       std::string output = input;

    std::replace(output.begin(), output.end(), '-', '+');
    std::replace(output.begin(), output.end(), '_', '/');    
if (output.size() % 4 != 0) {
        output.append(4 - (output.size() % 4), '=');
    }
return output;
}

//获取token的方法
bool getToken(std::string&token)
{
    string Authorization;
    Authorization=getenv("Authorization");
    if(Authorization.empty())return false;
    token=Authorization.substr(7);
    return true;
}

//认证中间件
static const std::string my_secret = "yoursaaaaa_3ecretkey";//用于验证token签名有效性的核心秘钥

class AuthMiddleware{

    public:
    //验证token
static bool verify_token(const std::string& token,std::string&userid, const std::string& secret=my_secret) {  
    try {  
        cerr<<"DEBUG------------------------------0"<<endl;
        cerr<<"DEBUG: TOKEN:"<<token;
        string tk=token;
        size_t pos=tk.find('\n');
        if(pos!=string::npos)
        {
            cerr<<"存在"<<endl;
            tk.pop_back();
        }
        cerr<<"DEBUG-----pop after: ------"<<tk;
       
        auto decoded = jwt::decode(tk);  
        cerr<<"DEBUG------------------------------0"<<endl;
    
        cerr<<"DEBUG------------------------------1"<<endl;
        auto verifier = jwt::verify()
        .allow_algorithm(jwt::algorithm::hs256{secret})
        .with_issuer("auth_server");  
        cerr<<"DEBUG------------------------------2"<<endl;
        
        verifier.verify(decoded);  
        cerr<<"DEBUG------------------------------3"<<endl;

        //获取userid
            if(decoded.has_payload_claim("userid"))
        {
            userid=decoded.get_payload_claim("userid").as_string();
            std::cerr << "Subject: " << userid << std::endl;
        }
        return true;  
    } 
    catch (const jwt::error::token_verification_exception& e) {  
        std::cerr << "Token验证失败: " << e.what() << std::endl;  
        return false;  
    }  
    
}
// 随机生成Token
static std::string generate_random_token( const std::string& userid,const std::string& secret=my_secret) {  
    auto token = jwt::create()  
        .set_issuer("auth_server")  
        .set_payload_claim("userid", jwt::claim(userid))  
         .set_issued_at(std::chrono::system_clock::now())  
         .set_expires_at(std::chrono::system_clock::now() + std::chrono::hours{1})  
        .sign(jwt::algorithm::hs256{secret});  
    return token;  
}
};